package cn.eonshine.cuba.lsms.modular;

import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import cn.eonshine.cuba.inf.common.http.InfStatus;
import cn.eonshine.cuba.inf.common.http.Message;
import cn.eonshine.cuba.inf.modular.log.service.ILogService;
import cn.eonshine.cuba.inf.modular.security.server.IKeyService;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.log4j.Log4j;

@Component
@Log4j
public abstract class CommonService<T> implements ICommonClientService {

	@Autowired
	protected IKeyService keyService;
	@Autowired
	protected ILogService  logService;
	
	
	
	
	@Override
	public void requestData(String listUrl, String updateUrl) {
		this.requestData(listUrl, updateUrl, null);
	}

	/**   
	 * <p>Title: requestData</p>   
	 * <p>Description: cn.eonshine.cuba.lsms.modular.ICommonClientService#requestData(java.lang.String)   
	 * @author: Alan
	 * @date:   2019-02-15 20:33:31
	 */
	@Override
	public void requestData(String listUrl, String updateUrl, String logType) {
		String urlRoot = keyService.getServerHttpRoot();
		String uuid=UUID.randomUUID().toString().replaceAll("-", "");
		// request data 请求数据
		Message message = keyService.clientRequestDataList(urlRoot+listUrl, null);
		// 1.将数据保存在本地
		// 2.将数据反馈回服务端，更新数据状态
		if (message.getStatus() == InfStatus.INF_OK && message.getCount() > 0) {
			// 将数据保存在本地
			List<T> msgDatas = (List<T>) JSONUtil.toList(JSONUtil.parseArray(message.getMsg()), getTClass());
			List<T> feadBackDataLists = Lists.newArrayList();
			List<T> errorDataLists = Lists.newArrayList();
			List<String> exceptions = Lists.newArrayList();
			int successCount=0;
			for (T t : msgDatas) {
				try {
					Object obj = dataHandle(t);
					if(obj == null) {
						errorDataLists.add(t);
						continue;
					}
					// 返回进行更新的数据
					feadBackDataHandle(obj, t, feadBackDataLists);
					successCount++;
				} catch (Exception e) {
					e.printStackTrace();
					// error data handle
					errorDataLists.add(t);
					String exception=ExceptionUtil.getMessage(e);
					exceptions.add(exception);
					log.error(e);
				}
			}
			logService.insertLog(message, uuid, "list request : "+listUrl, successCount, Joiner.on("\n").join(exceptions), logType);
			Map<String, List<T>> map = Maps.newHashMap();
			map.put(InfStatus.TRANS_STATUS.SUCCESS, feadBackDataLists);
			map.put(InfStatus.TRANS_STATUS.FAIL, errorDataLists);
			// 将数据反馈给服务端，将服务端数据状态更新
			Message changeLsmsFlag = keyService.clientRequestDataList(urlRoot+updateUrl, JSONUtil.toJsonStr(map));
			changeLsmsFlag.setCount(feadBackDataLists.size()+errorDataLists.size());
			logService.insertLog(changeLsmsFlag, uuid, "update request : "+updateUrl, (int)changeLsmsFlag.getCount(), null, logType);
		}
		/*else {
			logService.insertLog(message, uuid, "list request : "+listUrl, 0, null);
		}*/
	}
	
	/**
	 * 
	 * @Title: getTClass   
	 * @Description: get T class type
	 * @author: Alan
	 * @date:   2019-02-18 19:55:55
	 */
	private Class<T> getTClass() {
		@SuppressWarnings("unchecked")
		Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 
		return entityClass;
	}

	/**
	 * 
	 * @Title: dataHandle   
	 * @Description: handle data from dmz to lsms, return Object, used for fead back data
	 * @author: Alan
	 * @date:   2019-02-15 21:26:11
	 * @param obj Object from translate json covert to java bean object
	 * @return Object
	 * @throws Exception Exception
	 */
	protected abstract Object dataHandle(T obj) throws Exception;
	/**
	 * 
	 * @Title: feadBackDataHandle   
	 * @Description: return back data to delete from dmz server, data must containts: id, code, lsms_update 
	 * @author: Alan
	 * @date:   2019-02-15 20:39:02
	 * @param obj from dataHandle function result object
	 * @param t Object from translate json covert to java bean object
	 * @param feadBackDataLists an arraylist for return dmz server to handle data status
	 * @return return back data to delete from dmz server, data must containts: id, code, lsms_update 
	 * @throws Exception Exception
	 */
	protected abstract List<T> feadBackDataHandle(Object obj, T t, List<T> feadBackDataLists) throws Exception;

}
